home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Alles Voor Internet / Tout Pour Internet
/
alles voor internet.iso
/
MacInternet™
/
Telnet
/
NCSA
/
tn3270 2.4d7 source
/
tn3270
/
writesf.c
< prev
next >
Wrap
Text File
|
1992-04-17
|
43KB
|
1,518 lines
/*
* tn3270 for the Macintosh Source Code
* Brown University Computing and Information Services
* Version 2.4d7 April, 1992
* Copyright (c) 1988, 1989, 1990, 1991, 1992 by Brown University and by
* Peter John DiCamillo.
*
* Permission is granted to any individual or institution to use, copy,
* or redistribute the binary version of this software and its
* documentation provided this notice and the copyright notices are
* retained. Permission is granted to any individual or non-profit
* institution to use, copy, modify, or redistribute the source files
* of this software provided this notice and the copyright notices are
* retained. This software may not be distributed for profit, either
* in original form or in derivative works, nor can the source be
* distributed to other than an individual or a non-profit institution.
* Any individual or group interested in seeing and/or using these
* source files but who are prevented from doing so by the above
* constraints should contact Don Wolfe, Assistant Vice-President for
* Computer Systems at Brown University, (401) 863-7250, for possible
* software licensing of the source developed at Brown.
*
* Brown University and Peter John DiCamillo make no representations
* about the suitability of this software for any purpose.
*
* BROWN UNIVERSITY AND PETER JOHN DICAMILLO GIVE NO WARRANTY, EITHER
* EXPRESS OR IMPLIED, FOR THE PROGRAM AND/OR DOCUMENTATION PROVIDED,
* INCLUDING, WITHOUT LIMITATION, WARRANTY OF MERCHANTABILITY AND
* WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE.
*
*/
/* Code in this file supports WSF functions: Query Reply,
normal 3270 data (calls writetm), file transfer (calls
vmxfer), and 3179 graphics. */
/* Reference manuals for graphics support:
IBM 3179 G Color Graphics Display Station Description,
GA18-2261
Reference Information for Picture Interchange Format,
SC33-0244 (part of IBM 3270 PC/G or PC/GX library)
General 3270 data stream information:
IBM 3270 Information Display System Data Stream
Programmer's Reference, GA23-0059 (revision -3 includes
some 3179 information) */
/* Graphics has been tested using SAS version 5.16 with
device names of IBM3179 (SAS built-in support) and
GDDMPCGX (SAS calling GDDM Release 4). Test plots include
the output from the GTESTIT procedure, the "cowboy hat"
sample, and the BITNET topology maps. */
#if !defined(USEDUMP)
#include "maclib.h"
#include "termdef.h"
#include "tn3270funcs.h"
#include "globals.h"
#else
#pragma load "tn3270DumpFile"
#endif
#pragma segment 3270wsf
#define IAC 255 /* interpret as command: */
#define EOR 239 /* end of record (transparent mode) */
#define adMax 37 /* Color QuickDraw arithmetic drawing max mode */
#define adMin 39 /* Color QuickDraw arithmetic drawing min mode */
/* MacDraw PicComment codes we use */
#define picDwgBeg 130
#define picDwgEnd 131
#define picGrpBeg 140
#define picGrpEnd 141
/* LaserWriter PicComment codes we use */
#define SetLineWidth 182
extern struct Point sfppoint;
extern RGBColor realblack, realwhite;
/* Code labelled "temp" is included to allow writing debugging data for
graphics support to a file. Writing to the file is suppressed unless
"cf_dblevel" has been set by the main program. */
/*temp*/
#include "stdio.h"
/* write structured field */
void writesf(unsigned char *cmd, /* command, starting with WSF op-code */
short len, /* command length */
char init, /* false = data continued from last call */
cnr *cp)
{
short currlen, curroff, fieldlen;
unsigned char fieldid;
char readflg;
if (!init) return; /* currently, must get all data in one call */
if (len < 1) return;
currlen = len - 1; /* skip over wsf op-code */
curroff = 1;
while (currlen >= 3) {
fieldlen = cmd[curroff+1] + (cmd[curroff] << 8);
if (fieldlen == 0) fieldlen = currlen;
fieldid = cmd[curroff+2];
readflg = 0;
intwsf(fieldid, fieldlen, cmd+curroff, &readflg, cp);
if (readflg) break; /* command was a read of some sort */
curroff += fieldlen;
currlen -= fieldlen;
}
}
/* interpret one wsf field */
void intwsf(unsigned char id, /* wsf field type code */
short len, /* length of data */
unsigned char *data, /* data, starting with 2-byte length */
char *rdflag, /* return 1 if read which generates response */
cnr *cp)
{
/* temp */
cp->wsfdbg.wsf_op = id;
cp->wsfdbg.wsf_gr = cp->wsfdbg.grf_op = 0;
switch(id) {
case 0x01: /* read partition */
if (len < 5) break;
if ((data[4] == 0x02) || (data[4] == 0x03))
if (data[3] == 0xff)
wsfrpq(len, data, cp->newserver && (cp->cs.ext3270 == 0), cp);
(*rdflag) = 1;
break;
case 0x03: /* erase/reset */
if (data[3] & 0x80) {
cp->ewamode = 1; /* establish alternate screen size */
}
else {
cp->ewamode = 0; /* establish default screen size */
}
newmode(cp->ewamode, 0, cp);
clrscn(cp); /* clear text */
cp->drawpict = 1; /* force graphics clear */
clrpict(cp); /* clear graphics */
break;
case 0x06: /* load PS set */
/* ignore command to clear PS storage */
if ((len == 7) && (data[3] & 0x40)) break;
/* real PS load not supported */
hexdump(data, len, cp); /*temp*/
break;
case 0x09: /* set reply mode */
/* not supported */
hexdump(data, len, cp); /*temp*/
break;
case 0x0c: /* create partition */
/* not supported */
hexdump(data, len, cp); /*temp*/
break;
case 0x0f: /* graphic something */
if (cp->myWindow == 0) break;
writegf(data, len, cp);
break;
case 0x20: /* file transfer */
/* special field type made up for RMAC/WMAC transfer */
if (len < 4) break; /* at least one data byte */
cp->rbuf = data+3;
cp->rlen = len-3;
cp->sbuf = cp->readbuff+6;
vmxfer(cp); /* process file transfer command */
if (cp->slen == 0) break; /* send response, if generated */
(cp->readbuff)[0] = 0xd7;
cp->slen += 1;
(cp->readbuff)[5] = 0x88;
cp->rbsize = cp->slen + 5;
if (cp->tcpflg) {
(cp->readbuff)[cp->rbsize++] = IAC;
(cp->readbuff)[cp->rbsize++] = EOR;
}
senddata(1, cp);
break;
case 0x40: /* outbound 3270DS */
if (len < 5) return;
if (data[4] == 0x6f) { /* EAU */
funckey(10, 0, cp); /* simulate CLEAR key pressed */
cp->rdaid = 0x60;
break;
}
if ((data[3] == 0) && (data[4] == 0xf5)) {
cp->skipnewmode = 1; /* EW with PID = 0 keeps mode */
}
cp->ldvoff = 0; /* normal 3270 data stream */
writetm(data+4, len-4, 1, cp); /* update 3270 buffers */
cp->skipnewmode = 0; /* reset special flag */
invldscr(cp); /* display new contents */
endwcc(cp); /* post-write WCC functions */
break;
default:
hexdump(data, len, cp); /*temp*/
break;
}
}
/* Read Partition Query */
void wsfrpq(short len, unsigned char *data, char shortrsp, cnr *cp)
{
short i, j, listlen, reqtype, t, typecount, wsflen;
static unsigned char long_wsftypes[] = { /* all WSFR resources */
0x86, 0x87, 0x85, 0x81, 0xa6, 0x88, 0x80, 0x84, 0x96, 0x99,
0xa1, 0xa8, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb6, 0x00};
static unsigned char long_wsflist[] = { /* 0x01 if in default list */
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
static unsigned char short_wsftypes[] = { /* all WSFR resources */
0x85, 0x81, 0xa6, 0x80, 0xa1, 0x00};
static unsigned char short_wsflist[] = { /* 0x01 if in default list */
0x01, 0x01, 0x01, 0x01, 0x00};
unsigned char *wsftypes, *wsflist;
if (shortrsp) {
wsftypes = short_wsftypes;
wsflist = short_wsflist;
}
else {
wsftypes = long_wsftypes;
wsflist = long_wsflist;
}
switch (data[4]) {
case 0x02: /* Query */
listlen = 0;
reqtype = 1;
break;
case 0x03: /* Query List */
if (len < 6) return;
listlen = len - 6;
reqtype = (data[5] & 0xc0) >> 6;
if (reqtype == 3) return;
break;
default:
return;
}
typecount = strlen(wsftypes);
wsflen = 0;
for (i=0; i < typecount; i++) { /* loop through all possible responses;
include in response those requested */
t = wsftypes[i]; /* t = resource number */
if (reqtype == 2) { /* all types */
wsfadd(t, &wsflen, shortrsp, cp);
if (t == 179) wsfadd(254, &wsflen, shortrsp, cp); /* 2nd port response */
continue;
}
if ((reqtype == 1) && (wsflist[i] != 0)) { /* default types wanted */
wsfadd(t, &wsflen, shortrsp, cp);
if (t == 179) wsfadd(254, &wsflen, shortrsp, cp); /* 2nd port response */
continue;
}
if (listlen == 0) continue; /* listed types wanted */
for (j=0; j < listlen; j++)
if (data[j+6] == t) {
wsfadd(t, &wsflen, shortrsp, cp);
if (t == 179) wsfadd(254, &wsflen, shortrsp, cp); /* 2nd port response */
break;
}
}
/* return null response if no other */
if (wsflen == 0) wsfadd(255, &wsflen, shortrsp, cp);
(cp->readbuff)[0] = 0xd7; /* send the response, similarly to read modified */
wsflen += 1;
(cp->readbuff)[5] = 0x88; /* AID code = 0x88 (structured field) */
cp->rbsize = wsflen + 5;
if (cp->tcpflg) {
cp->readbuff[cp->rbsize++] = IAC;
cp->readbuff[cp->rbsize++] = EOR;
}
senddata(1, cp);
}
/* add resource no. "num" to response */
void wsfadd(short num, short *len, char shortrsp, cnr *cp)
{
unsigned char **rhandle;
short rlen, rnum;
void (*procptr)(void *resptr, cnr *cp);
unsigned char rscbuff[64];
rnum = num; /* default resource is argument */
switch(num) {
case 129: procptr = def_ua; /* usable area */
break;
case 166: procptr = def_ip; /* implicit partition */
break;
default: procptr = 0;
break;
}
if (cp->cs.altptsize == 12) {
switch(num) {
case 133: rnum = 252; /* character sets */
break;
case 182: rnum = 250; /* graphic symbol sets */
break;
default: break;
}
}
if (colormac && (!cp->cs.nocolor)) if (num == 134) rnum = 245;
if (shortrsp) if (num == 128) rnum = 244;
if (cp->cs.simps) { /* include PS character set response */
if (rnum == 133) rnum = 251;
if (rnum == 252) rnum = 253;
}
rhandle = (unsigned char **)GetResource('WSFR', rnum);
if (rhandle == 0) return; /* should report error here */
rlen = ((*rhandle)[0] << 8) + (*rhandle)[1];
/* modify response which depends on screen format */
if (procptr != 0) {
memcpy(rscbuff, (*rhandle), rlen);
(*procptr)(rscbuff, cp);
tcpmemcpy(cp->readbuff+6+(*len), rscbuff, &rlen, cp->tcpflg);
}
else {
tcpmemcpy(cp->readbuff+6+(*len), (*rhandle), &rlen, cp->tcpflg);
}
(*len) += rlen;
}
/* modify usable area response for screen format */
void def_ua(uareply *resptr, cnr *cp)
{
union {
unsigned short i;
unsigned char s[2];
} cvt;
resptr->w = 80;
resptr->h = 24;
switch (cp->cs.dfltptsize) {
case 12:
resptr->aw = 7;
resptr->ah = 16;
break;
default:
resptr->aw = 6;
resptr->ah = 12;
break;
}
cvt.i = cp->cs.altcols;
memcpy(resptr->waua, cvt.s, 2);
cvt.i = cp->cs.altrows;
memcpy(resptr->haua, cvt.s, 2);
switch (cp->cs.altptsize) {
case 12:
resptr->awaua = 7;
resptr->ahaua = 16;
break;
default:
resptr->awaua = 6;
resptr->ahaua = 12;
break;
}
}
/* modify implicit partition response for screen format */
void def_ip(ipreply *resptr, cnr *cp)
{
union {
unsigned short i;
unsigned char s[2];
} cvt;
cvt.i = 80;
memcpy(resptr->wd, cvt.s, 2);
cvt.i = 24;
memcpy(resptr->hd, cvt.s, 2);
cvt.i = cp->cs.altcols;
memcpy(resptr->wa, cvt.s, 2);
cvt.i = cp->cs.altrows;
memcpy(resptr->ha, cvt.s, 2);
switch (cp->cs.dfltptsize) {
case 12:
cvt.i = 7;
memcpy(resptr->wcd, cvt.s, 2);
cvt.i = 16;
memcpy(resptr->hcd, cvt.s, 2);
break;
default:
cvt.i = 6;
memcpy(resptr->wcd, cvt.s, 2);
cvt.i = 12;
memcpy(resptr->hcd, cvt.s, 2);
break;
}
switch (cp->cs.altptsize) {
case 12:
cvt.i = 7;
memcpy(resptr->wca, cvt.s, 2);
cvt.i = 16;
memcpy(resptr->hca, cvt.s, 2);
break;
default:
cvt.i = 6;
memcpy(resptr->wca, cvt.s, 2);
cvt.i = 12;
memcpy(resptr->hca, cvt.s, 2);
break;
}
}
void writegf(unsigned char *data, short len, cnr *cp) /* graphic data stream */
{
short i;
cp->wsfdbg.wsf_gr = data[3]; /*temp*/
pictcp = cp; /* for saving graphics */
switch(data[3]) {
case 0x0f: /* graphic data */
/* not supported */ /* controls inbound graphics data */
hexdump(data+7, len-7, cp); /*temp*/
break;
case 0x10: /* graphic picture */
if (data[5] & 0x80) {
cp->pleft = 0; /* if first, reset count */
initpict(cp); /* maybe start of new picture */
}
if (len < 8) break;
for (i=7; i < len; i++) grpparse(data[i], cp);
if (data[5] & 0x40) showpict(cp); /* if last, show result */
break;
case 0x11: /* graphic control */
if (data[5] & 0x80) {
cp->cleft = 0; /* if first, reset count */
initpict(cp); /* maybe start of new picture */
}
if (len < 8) break;
for (i=7; i < len; i++) grcparse(data[i], cp);
if (data[5] & 0x40) showpict(cp); /* if last, show result */
break;
case 0x1f: /* OEM data */
/* not supported */
hexdump(data+7, len-7, cp); /*temp*/
break;
default: hexdump(data+7, len-7, cp); /*temp*/
break;
}
}
void grpparse(unsigned char c, cnr *cp) /* interpret graphic picture data */
{
if (cp->pleft == 0) {
cp->pmode = cp->pcount = 0;
cp->pleft = 14;
}
switch (cp->pmode) {
case 0: /* processing segment header */
if (cp->pcount == 8) cp->ptemp1 = c;
if (cp->pcount == 9) cp->pleft = (cp->ptemp1 << 8) + c + 5;
if (cp->pcount == 13) {
cp->pmode = 1;
cp->pcount = 0;
}
else cp->pcount++;
break;
case 1: /* processing order */
if (cp->pcount == 0) {
cp->pboff = 0;
(cp->pictbuff)[cp->pboff++] = c;
if ((c==0x00) || (c==0x20) || (c==0xff)) {
exdraw(cp->pictbuff, cp->pboff, cp);
cp->pcount = 0;
}
else cp->pcount++;
break;
}
(cp->pictbuff)[cp->pboff++] = c;
if (cp->pcount == 1) {
if ((((cp->pictbuff)[0] <= 0x7f) &&
(((cp->pictbuff)[0] & 0x0f) >= 8)) || (c == 0)) {
exdraw(cp->pictbuff, cp->pboff, cp);
cp->pcount = 0;
}
else {
cp->ptemp1 = c; /* no. of operand bytes left */
cp->pcount++;
}
break;
}
cp->pcount++;
cp->ptemp1--;
if (cp->ptemp1 == 0) {
exdraw(cp->pictbuff, cp->pboff, cp);
cp->pcount = 0;
}
break;
default:
break;
}
cp->pleft--;
}
void exdraw(unsigned char *opdata, short len, cnr *cp) /* process drawing order */
{
short r, s;
union {
short ipos;
unsigned char cpos[2];
} cvt;
GrafPtr gp, dp;
short newcolor;
RGBColor rgbtemp;
unsigned char imagebuff[258];
unsigned char * imageptr;
short imgoffset;
GetPort(&gp);
if (cp->PictPtr != 0) {
SetPort(cp->PictPtr);
setgdev(cp);
}
else {
SetPort(cp->myWindow);
}
GetPort(&dp);
if (cf_dblevel == 3) { /* dump all graphics if level 3 */
cp->wsfdbg.grf_op = opdata[0]; /* temp */
hexdump(opdata, len, cp); /* temp */
}
switch(opdata[0]) {
case 0xa1: /* rel. line at current pos. */
r = opdata[1]/2;
s = 2;
MoveTo(sx(cp->xpos, cp), sy(cp->ypos, cp));
while (r > 0) {
cp->xpos += (char)opdata[s++];
cp->ypos += (char)opdata[s++];
myLineTo(sx(cp->xpos, cp), sy(cp->ypos, cp), cp);
r --;
}
break;
case 0x21: /* set current position */
cvt.cpos[0] = opdata[2];
cvt.cpos[1] = opdata[3];
cp->xpos = cvt.ipos;
cvt.cpos[0] = opdata[4];
cvt.cpos[1] = opdata[5];
cp->ypos = cvt.ipos;
break;
case 0x83: /* char. string at curr. pos. */
MoveTo(sx(cp->xpos, cp), sy(cp->ypos, cp)-2);
myDrawString(opdata+1, cp);
break;
case 0xc3: /* char. string at given pos. */
cvt.cpos[0] = opdata[2];
cvt.cpos[1] = opdata[3];
cp->xpos = cvt.ipos;
cvt.cpos[0] = opdata[4];
cvt.cpos[1] = opdata[5];
cp->ypos = cvt.ipos;
MoveTo(sx(cp->xpos, cp), sy(cp->ypos, cp));
opdata[5] = opdata[1] - 4;
if (opdata[5] < 0) opdata[5] = 0;
myDrawString(opdata+5, cp);
break;
case 0x85: /* fillet at current position */
/* see comment below for fillet at given position */
case 0x81: /* line at current position */
r = opdata[1]/4;
s = 2;
MoveTo(sx(cp->xpos, cp), sy(cp->ypos, cp));
while (r > 0) {
cvt.cpos[0] = opdata[s++];
cvt.cpos[1] = opdata[s++];
cp->xpos = cvt.ipos;
cvt.cpos[0] = opdata[s++];
cvt.cpos[1] = opdata[s++];
cp->ypos = cvt.ipos;
myLineTo(sx(cp->xpos, cp), sy(cp->ypos, cp), cp);
r --;
}
break;
case 0xc5: /* fillet at given position */
/* Too hard to do correctly for now, but at least */
/* draw the lines the curve should be tangent to, */
/* and update the current position. Fillet has */
/* not been encountered in any test plots. */
case 0xc1: /* line at given position */
cvt.cpos[0] = opdata[2];
cvt.cpos[1] = opdata[3];
cp->xpos = cvt.ipos;
cvt.cpos[0] = opdata[4];
cvt.cpos[1] = opdata[5];
cp->ypos = cvt.ipos;
MoveTo(sx(cp->xpos, cp), sy(cp->ypos, cp));
r = (opdata[1]-4)/4;
s = 6;
while (r > 0) {
cvt.cpos[0] = opdata[s++];
cvt.cpos[1] = opdata[s++];
cp->xpos = cvt.ipos;
cvt.cpos[0] = opdata[s++];
cvt.cpos[1] = opdata[s++];
cp->ypos = cvt.ipos;
myLineTo(sx(cp->xpos, cp), sy(cp->ypos, cp), cp);
r --;
}
break;
case 0xe1: /* relative line at given pos. */
cvt.cpos[0] = opdata[2];
cvt.cpos[1] = opdata[3];
cp->xpos = cvt.ipos;
cvt.cpos[0] = opdata[4];
cvt.cpos[1] = opdata[5];
cp->ypos = cvt.ipos;
MoveTo(sx(cp->xpos, cp), sy(cp->ypos, cp));
r = (opdata[1]-4)/2;
s = 6;
while (r > 0) {
cp->xpos += (char)opdata[s++];
cp->ypos += (char)opdata[s++];
myLineTo(sx(cp->xpos, cp), sy(cp->ypos, cp), cp);
r --;
}
break;
case 0xc7: /* full arc at given position */
/* Arcs are not supported yet, but at least move to */
/* the specified position. Arc commands have not */
/* been encountered in any test plots. */
cvt.cpos[0] = opdata[2];
cvt.cpos[1] = opdata[3];
cp->xpos = cvt.ipos;
cvt.cpos[0] = opdata[4];
cvt.cpos[1] = opdata[5];
cp->ypos = cvt.ipos;
break;
case 0x87: /* full arc at current position */
/* doesn't affect current position */
case 0x22: /* set arc parameters */
break;
case 0x26: /* set extended color */
setrgb(&newcolor, opdata[3], cp);
if (colormac && (!cp->cs.nocolor)) {
GetEntryColor(cp->myPalette, newcolor, &rgbtemp);
RGBForeColor(&rgbtemp); /* set foreground drawing color */
}
else {
if (newcolor == RGBblack) {
ForeColor(whiteColor);
}
else {
ForeColor(blackColor);
}
}
break;
case 0x0a: /* set color */
setrgb(&newcolor, opdata[1], cp);
if (colormac && (!cp->cs.nocolor)) {
GetEntryColor(cp->myPalette, newcolor, &rgbtemp);
RGBForeColor(&rgbtemp); /* set foreground drawing color */
}
else {
if (newcolor == RGBblack) {
ForeColor(whiteColor);
}
else {
ForeColor(blackColor);
}
}
break;
case 0x68: /* begin area */
cp->mypoly = OpenPoly(); /* create new polygon */
cp->aflags = opdata[1]; /* save flag bits */
cp->area_active = 1; /* remeber area is active */
break;
case 0x60: /* end area */
if (cp->area_active == 0) { /* check for datastream error */
break;
}
ClosePoly(); /* done saving stuff */
PenPat(&(cp->fillpat)); /* set fill pattern */
PaintPoly(cp->mypoly); /* draw it */
PenPat(&qd.black); /* restore default pattern */
if (cp->aflags & 0x40) FramePoly(cp->mypoly); /* handle outline */
KillPoly(cp->mypoly); /* dispose of it */
cp->area_active = 0; /* reset active flag */
break;
case 0x28: /* set pattern symbol (area fill pattern) */
setpat(&(cp->fillpat), opdata[1], cp);
break;
case 0x29: /* set marker symbol */
setmark(&(cp->markchar), opdata[1], cp);
break;
case 0xc2: /* marker at given position */
case 0x82: /* marker at current position */
r = opdata[1]/4;
s = 2;
while (r > 0) {
cvt.cpos[0] = opdata[s++];
cvt.cpos[1] = opdata[s++];
cp->xpos = cvt.ipos;
cvt.cpos[0] = opdata[s++];
cvt.cpos[1] = opdata[s++];
cp->ypos = cvt.ipos;
MoveTo(sx(cp->xpos, cp), sy(cp->ypos, cp)+4);
(cp->markstr)[1] = cp->markchar; /* make 1-character Pascal string */
myDrawString(cp->markstr, cp);
r --;
}
break;
case 0x18: /* set line type */
if (opdata[1] == 0) cp->linet = cp->dfltlt;
else cp->linet = opdata[1];
break;
case 0x19: /* set line width */
if (opdata[1] == 0) cp->linew = cp->dfltlw;
else cp->linew = opdata[1];
break;
case 0xd1: /* begin image */
case 0x91: /* begin image at current position */
cp->image_srcRect.top = 0;
cp->image_srcRect.left = 0;
cp->image_srcRect.bottom = 1;
if (opdata[0] == 0xd1) {
/* ignore if not in the format we expect*/
if (opdata[1] != 10) break;
if (opdata[6] != 0) break;
if (opdata[7] != 0) break;
/* define upper left corner of bitmap */
cvt.cpos[0] = opdata[2];
cvt.cpos[1] = opdata[3];
cp->image_dstRect.left = sx(cvt.ipos, cp);
cvt.cpos[0] = opdata[4];
cvt.cpos[1] = opdata[5];
cp->image_dstRect.top = sy(cvt.ipos, cp);
imgoffset = 8;
}
else {
/* ignore if not in the format we expect*/
if (opdata[1] != 6) break;
if (opdata[2] != 0) break;
if (opdata[3] != 0) break;
/* define upper left corner of bitmap */
cp->image_dstRect.left = sx(cp->xpos, cp);
cp->image_dstRect.top = sy(cp->ypos, cp);
imgoffset = 4;
}
cp->image_dstRect.bottom = cp->image_dstRect.top + 1;
/* convert width */
cvt.cpos[0] = opdata[imgoffset];
cvt.cpos[1] = opdata[imgoffset+1];
cp->image_srcRect.right = cvt.ipos;
cp->image_dstRect.right = cp->image_dstRect.left + cvt.ipos;
cp->image_srcBits.rowBytes = (cvt.ipos+7)/8;
if (cp->image_srcBits.rowBytes%2) cp->image_srcBits.rowBytes++;
/* convert height */
cvt.cpos[0] = opdata[imgoffset+2];
cvt.cpos[1] = opdata[imgoffset+3];
cp->image_rowcount = cvt.ipos;
cp->image_srcBits.bounds = cp->image_srcRect;
if (cp->pictopen) {
if (cp->image_dstRect.top < cp->ymin) cp->ymin = cp->image_dstRect.top;
if (cp->image_dstRect.top > cp->ymax) cp->ymax = cp->image_dstRect.top;
if (cp->image_dstRect.bottom < cp->ymin) cp->ymin = cp->image_dstRect.bottom;
if (cp->image_dstRect.bottom > cp->ymax) cp->ymax = cp->image_dstRect.bottom;
if (cp->image_dstRect.left < cp->xmin) cp->xmin = cp->image_dstRect.left;
if (cp->image_dstRect.left > cp->xmax) cp->xmax = cp->image_dstRect.left;
if (cp->image_dstRect.right < cp->xmin) cp->xmin = cp->image_dstRect.right;
if (cp->image_dstRect.right > cp->xmax) cp->xmax = cp->image_dstRect.right;
}
cp->image_active = 1;
break;
case 0x92: /* image data */
if (cp->image_active == 0) break;
if (cp->image_rowcount == 0) break;
cp->image_rowcount--;
imageptr = imagebuff;
if (((long)imageptr)%2) imageptr++;
memcpy(imageptr, opdata+2, opdata[1]);
cp->image_srcBits.baseAddr = imageptr;
if (colormac && (!cp->cs.nocolor)) {
GetBackColor(&rgbtemp);
if (cp->cs.invertbw) {
RGBBackColor(&realwhite);
}
else {
RGBBackColor(&realblack);
}
CopyBits(&(cp->image_srcBits), &(dp->portBits),
&(cp->image_srcRect), &(cp->image_dstRect), cp->copymode, 0L);
RGBBackColor(&rgbtemp);
}
else {
CopyBits(&(cp->image_srcBits), &(dp->portBits),
&(cp->image_srcRect), &(cp->image_dstRect), cp->copymode, 0L);
}
cp->image_dstRect.top++;
cp->image_dstRect.bottom++;
break;
case 0x93: /* end image */
if (cp->image_active == 0) break;
cp->image_active = 0;
break;
case 0x0c: /* set foreground mix */
setmixmode(opdata[1], cp);
break;
/* The following are not easily implemented using QuickDraw; */
/* none of these appear to be needed for the test plots to */
/* display correctly: */
case 0x33: /* set character cell */
case 0x34: /* set character angle */
case 0x35: /* set character shear */
case 0x38: /* set character set */
case 0x3a: /* set character direction */
case 0x37: /* set marker cell */
case 0xff: /* end of symbol definition */
/* The following are documented by IBM to be ignored in files */
/* imported into GGXA, and are unlikely to be used. None of */
/* of the test plots need them. */
case 0x0d: /* set background mix */
/* no-op for 3179 */
case 0x39: /* set character precision */
case 0x3b: /* set marker precision */
case 0x3c: /* set marker set */
case 0x08: /* set pattern set */
case 0x43: /* set pick identifier */
case 0x04: /* segment characteristics */
case 0x3e: /* end prologue */
case 0x71: /* end segment */
/* these do nothing by definition */
case 0x01: /* comment */
case 0x00: /* no-op */
break;
default:
if (cf_dblevel == 3) break; /* for level 3, already dumped */
cp->wsfdbg.grf_op = opdata[0]; /* temp */
hexdump(opdata, len, cp); /* temp */
break;
}
if (cp->PictPtr != 0) resetgdev();
SetPort(gp);
}
void grcparse(unsigned char c, cnr *cp)
{
if (cp->cleft == 0) {
cp->cmode = cp->ccount = 0;
cp->cleft = 12;
}
switch (cp->cmode) {
case 0: /* processing procedure header */
if (cp->ccount == 8) cp->ctemp1 = c;
if (cp->ccount == 9) cp->cleft = (cp->ctemp1 << 8) + c + 3;
if (cp->ccount == 11) {
cp->cmode = 1;
cp->ccount = 0;
}
else cp->ccount++;
break;
case 1: /* processing procedural instruction */
if (cp->ccount == 0) {
cp->cboff = 0;
(cp->ctlbuff)[cp->cboff++] = c;
if (c == 0x00) {
exctl(cp->ctlbuff, cp->cboff, cp);
cp->ccount = 0;
}
else cp->ccount++;
break;
}
(cp->ctlbuff)[cp->cboff++] = c;
if (cp->ccount == 1) {
if (((cp->ctlbuff)[0] >= 0x08) && ((cp->ctlbuff)[0] <= 0x0f)) {
exctl(cp->ctlbuff, cp->cboff, cp);
cp->ccount = 0;
}
else {
cp->ctemp1 = c; /* no. of operand bytes left */
cp->ccount++;
}
break;
}
cp->ccount++;
cp->ctemp1--;
if (cp->ctemp1 == 0) {
exctl(cp->ctlbuff, cp->cboff, cp);
cp->ccount = 0;
}
break;
default:
break;
}
cp->cleft--;
}
void exctl(unsigned char *opdata, short len, cnr *cp) /* process control command */
{
GrafPtr gp;
char setdflt;
short i;
GetPort(&gp);
if (cp->PictPtr != 0) {
SetPort(cp->PictPtr);
setgdev(cp);
}
else SetPort(cp->myWindow);
if (cf_dblevel == 3) { /* for level 3, dump all graphics */
cp->wsfdbg.grf_op = opdata[0]; /* temp */
hexdump(opdata, len, cp); /* temp */
}
switch(opdata[0]) {
case 0x0a: /* erase graphics space */
clrpict(cp);
break;
case 0x00: /* no operation */
case 0x01: /* comment */
case 0x0f: /* stop draw */ /* no-op for 3179 */
break;
case 0x21: /* set current defaults */
/* untested- not used by test plots */
setdflt = (opdata[5] & 0x80) == 0;
switch(opdata[2]) { /* SET code */
case 0x00: /* drawing attributes */
i = 6; /* offset for next data byte */
if (opdata[3] & 0x80) { /* color specified */
if (setdflt) cp->dfltcolor = 4; /* green */
else cp->dfltcolor = opdata[i+1];
i += 2;
}
if (opdata[3] & 0x20) { /* foreground mix specified */
if (setdflt) cp->dfltmix = 2; /* overpaint */
else cp->dfltmix = opdata[i];
i++;
}
break;
case 0x01: /* line attributes */
i = 6; /* offset for next data byte */
if (opdata[3] & 0x80) { /* line type specified */
if (setdflt) cp->dfltlt = 7; /* default is solid line */
else cp->dfltlt = opdata[i];
i++;
}
if (opdata[3] & 0x40) /* line width specified */
if (setdflt) cp->dfltlw = 1; /* default is 1 pixel wide */
else cp->dfltlw = opdata[i];
break;
case 0x02: /* character attributes */
break; /* not supported */
case 0x03: /* marker attributes */
i = 6; /* offset for next data byte */
if (opdata[3] & 0x40) /* cellsize */
i += 4;
if (opdata[3] & 0x10) /* precision */
i += 1;
if (opdata[3] & 0x08) /* symbol set */
i += 1;
if (opdata[3] & 0x01) /* marker symbol */
if (setdflt) cp->dfltmarker = 0xb5; /* diamond */
else setmark(&(cp->dfltmarker), opdata[i], cp);
break;
case 0x04: /* pattern attributes */
i = 6; /* offset for next data byte */
if (opdata[3] & 0x08) /* symbol set */
i += 1;
if (opdata[3] & 0x01) /* pattern symbol */
if (setdflt) setpat(&(cp->dfltpat), 16, cp);
else setpat(&(cp->dfltpat), opdata[i], cp);
break;
case 0x0b: /* arc parameters */
break; /* not supported */
default: /* reserved; SAS & GDDM use 0x05, 0x07 */
if (cf_dblevel == 3) break; /* for level 3, dumped already */
cp->wsfdbg.grf_op = opdata[0]; /* temp */
hexdump(opdata, len, cp); /* temp */
break;
}
break;
/* no support for the graphics cursor */
case 0x08: /* attach graphic cursor */
case 0x09: /* detach graphic cursor */
case 0x31: /* set graphic cursor pos. */
break;
default:
if (cf_dblevel == 3) break; /* for level 3, dumped already */
cp->wsfdbg.grf_op = opdata[0]; /* temp */
hexdump(opdata, len, cp); /* temp */
break;
}
if (cp->PictPtr != 0) resetgdev();
SetPort(gp);
}
void clrpict(cnr *cp) /* erase graphics space */
{
GrafPtr gp;
RGBColor rgbtemp;
static unsigned char endarea[] = {0x60, 0};
static unsigned char endimage[] = {0x93, 0};
cp->pndclr = 0; /* reset pending clear */
if (cp->drawpict == 0) return; /* nothing to do if no graphics */
if (cp->area_active) { /* end area if still active */
exdraw(endarea, 2, cp); /* execute end area command */
}
if (cp->image_active) { /* end image if still active */
exdraw(endimage, 2, cp); /* execute end image command */
}
if (cp->pictopen) { /* close PICT file if open */
closepictfile(cp);
}
GetPort(&gp); /* save current GrafPort */
if (cp->PictPtr == 0) { /* erase port we draw in */
SetPort(cp->myWindow);
EraseRect(&((cp->myWindow)->portRect));
setmixmode(0, cp); /* set default pen mode */
}
else {
SetPort(cp->PictPtr);
setgdev(cp);
EraseRect(&(cp->PictPort.portRect));
setmixmode(0, cp);
resetgdev();
}
if (colormac && (!cp->cs.nocolor)) {
SetPort(cp->WritePtr); /* restore background color */
if (cp->textmap) setgdev(cp);
GetEntryColor(cp->myPalette, RGBback, &rgbtemp);
RGBBackColor(&rgbtemp);
if (cp->textmap) resetgdev();
}
SetPort(gp); /* restore GrafPort */
cp->drawpict = 0; /* don't show graphics any more */
cp->newpict = 1; /* next order starts new picture */
if (cp->pendalign) { /* align bitmaps if changed during display */
alignbitmaps(cp);
newstat(cp);
}
invldscr(cp); /* force screen to be redrawn */
/* end saving PICT file */
}
void initpict(cnr *cp) /* initialize at start of new picture */
{
if (!(cp->newpict)) return;
cp->drawpict = 1; /* clear initial screen */
clrpict(cp); /* (resets drawpict, sets newpict) */
cp->newpict = 0; /* no longer new picture */
/* begin saving PICT file */
if (cp->savepict && (cp->PictPtr != 0)) {
openpictfile(cp);
}
}
void showpict(cnr *cp) /* cause graphics data to be displayed */
{
GrafPtr gp;
RGBColor rgbtemp;
cp->drawpict = 1; /* include graphics in screen updates */
if (colormac && (!cp->cs.nocolor)) { /* change text background to black or white */
GetPort(&gp);
SetPort(cp->WritePtr);
if (cp->textmap) setgdev(cp);
if (cp->cs.invertbw) GetEntryColor(cp->myPalette, RGBwhite, &rgbtemp);
else GetEntryColor(cp->myPalette, RGBblack, &rgbtemp);
RGBBackColor(&rgbtemp);
SetPort(gp);
if (cp->textmap) resetgdev();
}
invldscr(cp); /* invalidate screen to force update */
}
/* The following two function are simple now, since tn3270's response to
WSF Query Reply now accurately describes the Mac screen dimensions.
Both SAS and GDDM adapt to this very well. */
short sx(short x, cnr *cp) /* convert data stream x-coordinate to Mac coordinate */
{
register short r;
/* if (PictPtr == 0) {
if (cur_ptsize == 12) r = x + 286;
else r = x + 246;
}
else {
if (cur_ptsize == 12) r = x + 318;
else r = x + 255;
} */
r = x + cp->hpixsize/2;
if (cp->PictPtr == 0) {
r += cp->textRect.left;
}
if (cp->pictopen) {
if (r < cp->xmin) cp->xmin = r;
if (r > cp->xmax) cp->xmax = r;
}
return(r);
}
short sy(short y, cnr *cp) /* convert data stream y-coordinate to Mac coordinate */
{
register short r;
/* if (PictPtr == 0) {
if ((cur_ptsize == 9) && (cur_rows == 24)) r = 139 - y;
else r = 188 - y;
}
else {
if ((cur_ptsize == 9) && (cur_rows == 24)) r = 146 - y;
else r = 195 - y;
} */
r = (cp->vpixsize - 19)/2 - y;
if (cp->PictPtr == 0) {
r += cp->textRect.top;
}
if (cp->pictopen) {
if (r < cp->ymin) cp->ymin = r;
if (r > cp->ymax) cp->ymax = r;
}
return(r);
}
void myLineTo(short x, short y, cnr *cp)
{
switch (cp->linet) { /* set pen pattern for line type */
case 8: /* invisible */
PenPat(&qd.white);
break;
default: /* all other, until I figure out how to do this */
PenPat(&qd.black);
break;
}
/* set pen width as requested */
if (cp->linew == 0) PenSize(1, 1);
else PenSize(cp->linew, cp->linew);
LineTo(x, y); /* draw the line */
PenPat(&qd.black); /* restore QuickDraw defaults */
PenSize(1, 1);
}
void myDrawString(unsigned char *s, cnr *cp)
/* s is a Pascal string */
{
short i;
unsigned char xlstr[256]; /* translated copy of string */
Point penloc;
short texttop, textleft, textbottom, textright;
FontInfo fi;
if (s[0] == 0) return; /* just return if null string */
xlstr[0] = s[0]; /* copy the string */
memcpy(xlstr+1, s+1, s[0]);
if (cp->nl_handle != 0) {
for (i=1; i <= xlstr[0]; i++) /* translate EBCDIC for language */
xlstr[i] = (cp->nltab)[xlstr[i]];
}
if (cp->pictopen && (xtabh != 0)) {
for (i=1; i <= xlstr[0]; i++) /* translate string to ASCII */
xlstr[i] = (*xtabh)[xlstr[i]];
}
if (cp->pictopen) {
GetPen(&penloc);
textleft = penloc.h;
GetFontInfo(&fi);
texttop = penloc.v + fi.ascent;
textbottom = penloc.v - fi.descent - fi.leading;
}
DrawString(xlstr);
if (cp->pictopen) {
GetPen(&penloc);
textright = penloc.h;
if (texttop > cp->ymax) cp->ymax = texttop;
if (texttop < cp->ymin) cp->ymin = texttop;
if (textbottom > cp->ymax) cp->ymax = textbottom;
if (textbottom < cp->ymin) cp->ymin = textbottom;
if (textleft < cp->xmin) cp->xmin = textleft;
if (textleft > cp->xmax) cp->xmax = textleft;
if (textright < cp->xmin) cp->xmin = textright;
if (textright > cp->xmax) cp->xmax = textright;
}
}
/* set newcolor from data stream code */
void setrgb(short *newcolor, unsigned char code, cnr *cp)
{
if ((code == 0) || (code == 16)) code = cp->dfltcolor;
switch(code) {
case 1: /* blue */
case 9: /* dark blue */
(*newcolor) = RGBblue;
break;
case 2: /* red */
case 10: /* orange */
(*newcolor) = RGBred;
break;
case 3: /* pink */
case 11: /* purple */
(*newcolor) = RGBpink;
break;
case 4: /* green */
case 12: /* dark green */
(*newcolor) = RGBgreen;
break;
case 5: /* turquoise */
case 13: /* dark turquoise */
(*newcolor) = RGBturquoise;
break;
case 6: /* yellow */
case 14: /* mustard */
(*newcolor) = RGByellow;
break;
case 7: /* neutral */
case 15: /* gray */
if (cp->cs.invertbw) (*newcolor) = RGBblack;
else (*newcolor) = RGBwhite;
break;
case 8: /* background */
if (cp->cs.invertbw) (*newcolor) = RGBwhite;
else (*newcolor) = RGBblack;
break;
default:
if (cp->cs.invertbw) (*newcolor) = RGBblack;
else (*newcolor) = RGBwhite;
break;
}
}
/* convert marker code to character */
void setmark(unsigned char *mark, unsigned char code, cnr *cp)
{
switch(code) {
case 0x00: /* default */
(*mark) = cp->dfltmarker;
break;
case 0x01: /* cross */
(*mark) = 0x46; /* sort of a cross */
break;
case 0x02: /* plus */
(*mark) = 0x4e; /* normal plus */
break;
case 0x05: /* 6-point star */
case 0x06: /* 8-point star */
(*mark) = 0x5c; /* normal asterisk */
break;
default:
(*mark) = 0xb5; /* solid diamond */
break;
}
}
/* define pattern from code */
void setpat(PatPtr pat, unsigned char code, cnr *cp)
{
static Pattern pattab[16] = {
{0xdd, 0xff, 0x77, 0xff, 0xdd, 0xff, 0x77, 0xff}, /* 87.5% gray */
{0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77}, /* 75% gray */
{0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55}, /* 50% gray */
{0xaa, 0x00, 0x55, 0x00, 0xaa, 0x00, 0x55, 0x00}, /* 25% gray */
{0x88, 0x00, 0x22, 0x00, 0x88, 0x00, 0x22, 0x00}, /* 12.5% gray */
{0x80, 0x00, 0x08, 0x00, 0x80, 0x00, 0x08, 0x00}, /* 6.25% gray */
{0x80, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00}, /* 3.125% gray */
{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 1.5625% gray */
{0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88}, /* vertical lines */
{0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00}, /* horizontal lines */
{0x11, 0x11, 0x22, 0x22, 0x44, 0x44, 0x88, 0x88}, /* "/" diags, less steep */
{0x11, 0x22, 0x44, 0x88, 0x11, 0x22, 0x44, 0x88}, /* "/" diags., 45 degrees */
{0x88, 0x88, 0x44, 0x44, 0x22, 0x22, 0x11, 0x11}, /* "\" diags., less steep */
{0x88, 0x44, 0x22, 0x11, 0x88, 0x44, 0x22, 0x11}, /* "\" diags., 45 degrees */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* white (none) */
{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}}; /* black (solid) */
if (code == 0) memcpy(pat, &(cp->dfltpat), 8);
else {
if (code > 16) code = 16;
memcpy(pat, &(pattab[code-1]), 8);
}
}
void setmixmode(short mode, cnr *cp)
{
if (mode == 0) mode = cp->dfltmix;
switch(mode) {
case 1: /* "mix" colors */
if (colormac && (!cp->cs.nocolor)) {
if (cp->cs.invertbw) {
PenMode(adMin);
cp->copymode = adMin;
}
else {
PenMode(adMax);
cp->copymode = adMax;
}
}
else {
PenMode(patOr);
cp->copymode = srcOr;
}
break;
default: /* overpaint */
PenMode(patCopy);
cp->copymode = srcCopy;
break;
}
}
void openpictfile(cnr *cp)
{
Point where;
DlgHookProcPtr dlgHook;
SFReply reply;
OSErr rc;
short i;
long longzero = 0;
long iocount;
GrafPtr gp;
where = sfppoint;
dlgHook = 0;
arrowcursor();
SFPutFile(where, "\pSave graphics in:",
cp->pict_fName, dlgHook, &reply);
if (reply.good == 0) return;
(cp->pict_fName)[0] = reply.fName[0]; /* save filename */
memcpy(cp->pict_fName+1, reply.fName+1, reply.fName[0]);
rc = FSDelete(&reply.fName, reply.vRefNum); /* delete existing file */
if ((rc != 0) && (rc != -43)) { /* file not found is ok */
stoperr(wpictalrt, cp);
return;
}
rc = Create(&reply.fName, reply.vRefNum, 'MDRW', 'PICT');
if (rc != 0) {
stoperr(wpictalrt, cp);
return;
}
rc = FSOpen(&reply.fName, reply.vRefNum, &(cp->pictfref));
if (rc != 0) {
stoperr(wpictalrt, cp);
return;
}
/* write 512-byte header */
for (i=0; i < 512/4; i++) {
iocount = 4;
rc = FSWrite(cp->pictfref, &iocount, &longzero);
if (rc != 0) break;
}
/* write fixed fields of PICT */
if (rc == 0) {
for (i=0; i < (sizeof(short) + sizeof(Rect))/2; i++) {
iocount = 2;
rc = FSWrite(cp->pictfref, &iocount, &longzero);
if (rc != 0) break;
}
}
if (rc != 0) { /* clean up if write error */
FSClose(cp->pictfref);
FSDelete(&reply.fName, reply.vRefNum);
stoperr(wpictalrt, cp);
return;
}
cp->pictvref = reply.vRefNum;
cp->pictopen = 1;
cp->picterr = 0;
cp->xmin = cp->ymin = 0x7fff;
cp->xmax = cp->ymax = 0x8000;
if (colormac && (!cp->cs.nocolor)) SetStdCProcs(&(cp->myProcs));
else SetStdProcs((QDProcs *)&(cp->myProcs));
(cp->PictPtr)->grafProcs = (QDProcs *)&(cp->myProcs);
cp->myProcs.putPicProc = (Ptr)myStdPutPic;
GetPort(&gp);
SetPort(cp->PictPtr);
TextFont(4);
cp->picthandle = 0;
cp->picthandle = OpenPicture(&(cp->PictPtr)->portRect);
ShowPen();
PicComment(picDwgBeg, 0, 0L); /* start MacDraw Picture */
PicComment(picGrpBeg, 0, 0L); /* begin a group */
cp->theWidth = NewHandle((Size)sizeof(Point));
if (cp->theWidth != 0) {
((Point *)(*(cp->theWidth)))->v = 1;
((Point *)(*(cp->theWidth)))->h = 3; /* use 1/3 normal width */
PicComment(SetLineWidth, sizeof(Point), cp->theWidth); /* set new line width */
}
cp->pictcount = sizeof(Picture);
SetPort(gp);
}
void closepictfile(cnr *cp)
{
OSErr rc;
GrafPtr gp;
long iocount, pictpos;
struct pictfixed {
short pictlen;
Rect pictrect;
} pf;
GetPort(&gp);
SetPort(cp->PictPtr);
PicComment(picGrpEnd, 0, 0L); /* end a group */
PicComment(picDwgEnd, 0, 0L); /* end MacDraw Picture */
HidePen();
ClosePicture();
TextFont(cp->stdfont);
/* save the current file position */
if (cp->picterr == 0) {
cp->picterr = GetFPos(cp->pictfref, &pictpos);
}
/* set position after MacDraw header */
if (cp->picterr == 0) {
cp->picterr = SetFPos(cp->pictfref, fsFromStart, (long)512);
}
/* copy fixed picture fields */
memcpy(&pf, (Ptr)(*(cp->picthandle)), sizeof(struct pictfixed));
/* adjust rectangle to match actual plot */
pf.pictrect.top = cp->ymin;
pf.pictrect.left = cp->xmin;
pf.pictrect.bottom = cp->ymax;
pf.pictrect.right = cp->xmax;
/* write the final fixed picture fields */
if (cp->picterr == 0) {
iocount = sizeof(struct pictfixed);
cp->picterr = FSWrite(cp->pictfref, &iocount, &pf);
}
/* reset the file position to the end */
if (cp->picterr == 0) {
cp->picterr = SetFPos(cp->pictfref, fsFromStart, pictpos);
}
KillPicture(cp->picthandle);
SetPort(gp);
(cp->PictPtr)->grafProcs = 0;
rc = FSClose(cp->pictfref);
if (cp->theWidth != 0) {
DisposHandle(cp->theWidth);
}
cp->pictopen = 0;
if ((rc != 0) || (cp->picterr != 0)) {
stoperr(wpictalrt, cp);
FSDelete(cp->pict_fName, cp->pictvref);
}
}
pascal void myStdPutPic(Ptr dataPtr, unsigned short byteCount)
{
long iocount;
if (pictcp->picterr != 0) return;
iocount = byteCount;
pictcp->pictcount += byteCount;
pictcp->picterr = FSWrite(pictcp->pictfref, &iocount, dataPtr);
if (pictcp->picthandle != 0) (*(pictcp->picthandle))->picSize = pictcp->pictcount;
}
void hexdump(unsigned char *data, short len, cnr *cp) /*temp*/
{
short count, i;
FILE * fp;
if (!cf_dblevel) return;
if (cp->openflg == 0) {
fp = fopen("Ram:wsfdebug", "w");
if (fp == 0) return;
cp->openflg = 1;
}
else {
fp = fopen("Ram:wsfdebug", "a");
if (fp == 0) return;
}
fprintf(fp, "wsf_op = %x, wsf_gr = %x, grf_op = %x, length = %d\n",
cp->wsfdbg.wsf_op, cp->wsfdbg.wsf_gr, cp->wsfdbg.grf_op, len);
count = 0;
for (i=0; i < len; i++) {
fprintf(fp, "%02x", data[i]);
count++;
if (count == 32) {
fprintf(fp, "\n");
count = 0;
}
}
if (count != 0) fprintf(fp, "\n");
fprintf(fp, "\n");
fclose(fp);
}